package com.dong.router.compiler

import com.dong.router.compiler.model.TargetInfo
import com.dong.router.compiler.utils.firstToUpperCase
import com.dong.router.annotation.Router
import com.dong.router.compiler.constant.Constants
import com.google.auto.service.AutoService
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeSpec
import java.lang.Exception
import javax.annotation.processing.*
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement

@AutoService(Processor::class)
class RouterProcessor: AbstractProcessor() {

    /**
     * 该注解器需要处理的注解
     */
    override fun getSupportedAnnotationTypes(): MutableSet<String> {
        return mutableSetOf<String>().apply {
            add(Router::class.java.canonicalName)
        }
    }

    /**
     * 提取注解的信息，保存处理或者生成代码
     */
    override fun process(annotations: MutableSet<out TypeElement>?, env: RoundEnvironment?): Boolean {
        //注解修饰的Element不存在，直接返回
        if (annotations.isNullOrEmpty()) {
            return false
        }

        env?.run {
            //获取注解修饰的Element集合
            val elements  = getElementsAnnotatedWith(Router::class.java)
            val map = mutableMapOf<String, MutableList<TargetInfo>>()
            for (element in elements) {
                //遍历Element
                if(element is TypeElement){
                    //获取Element的Router注解信息
                    val router = element.getAnnotation(Router::class.java)
                    var key = with(if(router.module.isNullOrBlank()) router.path else router.module) {
                        firstToUpperCase(this)
                    }
                    if(map[key] == null) {
                        map[key] = mutableListOf()
                    }
                    map[key]!!.add(TargetInfo(element, router))
                }
            }

            //对注解信息作相应处理（创建代码等）
            if(!map.isNullOrEmpty()){
                generateRegisterCode(map)
            }
        }
        return true
    }

    private fun generateRegisterCode(map: MutableMap<String, MutableList<TargetInfo>>) {
        for (entry in map) {
            //1.创建方法
            val methodBuilder = MethodSpec.methodBuilder("register") //方法名
                .addModifiers(Modifier.PUBLIC)
            for (targetInfo in entry.value) {
                methodBuilder.addStatement("${Constants.GENERATE_PACKAGE_NAME}.RouterManager.getInstance().register(\"${targetInfo.router.path}\", ${targetInfo.typeElement}.class)")
            }

            //2.创建类
            val typeSpec = TypeSpec.classBuilder("${Constants.GENERATE_CLASS_NAME_REGISTER}$$${entry.key}") //类名
                .addModifiers(Modifier.PUBLIC)
                .addMethod(methodBuilder.build())
                .addSuperinterface(ClassName.get(Class.forName(Constants.GENERATE_SUPER_INTERFACE_NAME)))
                .addJavadoc("Generated by Router. Do not edit it!\n")
                .build()

            //3.创建文件
            try {
                JavaFile.builder(Constants.GENERATE_PACKAGE_NAME, typeSpec) //文件所在的包和对应的类
                    .build()
                    .writeTo(processingEnv.filer)
            } catch (e: Exception) {
                e.printStackTrace();
            }
        }
    }
}